Imports VB = Microsoft.VisualBasic

Friend Class frmPreviewData
    Inherits System.Windows.Forms.Form
    Private WithEvents dgvhData As WRDB.Controls.DGVEditor

    Private WithEvents dgvhDefaults As WRDB.Controls.DGVEditor
    Private WithEvents dgvhHeader As WRDB.Controls.DGVEditor

    'following contains all valid headings for columns by category as semi-colon separated lists
    '(it will be easy and fast to do string search for valid entries)

    Dim HeaderFile As String

    Private Initializing As Boolean

    Dim TreeList As String 'contains pcodes and all field names for drop-down display
    Private TreeviewForm As frmTreeView

    Private WRDBImport As clsWRDBImport

    Friend Sub New(ByRef _WRDBImport As clsWRDBImport)
        Me.New()
        WRDBImport = _WRDBImport
        With WRDBImport
            TreeList = String.Format("Ignore;Stations;>;{0};<;PCodes;>;{1};<;Data Fields;>;{2};<;Date & Time Fields;>;{3};<;Day of Month Fields;>;{4};<;Hour of Day Fields;>;{5};<;Month Fields;>;{6};<;Storet Fields;>;{7};<;Convert Fields;>;{8};<;Station Fields;>;{9};<;PCode Fields;>;{10};<;CCode Fields;>;{11};<;RCode Fields;>;{12};<;QCode Fields;>;{13};<;Station Group Fields;>;{14};<;PCode Group Fields;>;{15};<;Conversion Group Fields;>;{16};<;Branch Fields;>;{17};<;Agency Fields;>;{18};<;FIPS Code Fields;>;{19};<;WQX Fields;>;{20};<;Validation Fields;>;{21};<", .ValidValueList(clsWRDBImport.enumTables.tStationTable), .ValidValueList(clsWRDBImport.enumTables.tPCodeTable), .DataFieldList, .DateFieldList, .DayList, .HourList, .MonthList, .StoretFieldList, .ConvertFieldList, .StationFieldList, .PCodeFieldList, .CCodeFieldList, .RCodeFieldList, .QCodeFieldList, .StationGroupFieldList, .PCodeGroupFieldList, .ConvGroupFieldList, .BranchFieldList, .AgencyFieldList, .FIPSCodeFieldList, .WQXMethodFieldList, .ValidationFieldList)
        End With
    End Sub

    ''' <summary>
    ''' Open and read test file or database table and place info into header data structure according to currently selected file format. 
    ''' </summary>
    ''' <param name="SkipPreview">True to bypass display of preview and just do import</param>
    ''' <returns></returns>
    ''' <remarks>When done, file table remains open and positioned at first line in the body.
    '''             Note: some legacy files are formatted as, say, Tabular, but don't have the
    '''             TABULAR keyword at the top. These files will not be automatically recognized.
    '''             The user will either have to add the appropriate keyword, or remove the
    '''             header entirely and respecify it.</remarks>
    Public Function ReadHeader(Optional ByRef SkipPreview As Boolean = False) As Boolean
        Dim sr As IO.StreamReader = Nothing
        Try
            Dim r, c As Integer
            Dim i As Short

            With WRDBImport

                .WRDBDataSource.Rewind()

                Dim IniFile As WRDB.IniFile.clsIniFile = Nothing

                If Not SkipPreview Then
                    GetHeaderFromForm()
                    If HeaderFile <> "" Then
                        IniFile = New WRDB.IniFile.clsIniFile(HeaderFile, True)
                        .UseHeadings = GetKey(IniFile, "General", "UseHeadings", CStr(True))
                        .DataFormat = GetKey(IniFile, "General", "Format", CStr(clsWRDBImport.enumFormat.Tabular))
                    End If
                End If

                Initializing = True 'don't allow changes to form to call back here

                .Increment = 1
                .IncrementType = clsWRDBImport.enumIncrement.incrRow

                Select Case .DataFormat

                    Case clsWRDBImport.enumFormat.Tabular

                        .WRDBDataSource.Rewind()

                        'line 1
                        If Not .WRDBDataSource.Read Or .WRDBDataSource.NumItems < 2 Then Return False
                        .Description = .WRDBDataSource.Items(1)

                        'line 2
                        If Not .WRDBDataSource.Read Or .WRDBDataSource.NumItems < 4 Then Return False
                        .StationID = .WRDBDataSource.Items(0).ToUpper

                        .NumCols = Max(1, Val(.WRDBDataSource.Items(1)))
                        .Increment = Max(1, Val(IIf(Val(.WRDBDataSource.Items(3)) = 0, .WRDBDataSource.Items(2), .WRDBDataSource.Items(3))))
                        .IncrementType = IIf(Val(.WRDBDataSource.Items(3)) = 0, clsWRDBImport.enumIncrement.incrRow, clsWRDBImport.enumIncrement.incrTime)
                        .Multiplier = 1

                        'lines 3, 4, and 5
                        For r = 0 To 2
                            If Not .WRDBDataSource.Read Then Return False
                            For c = 0 To .NumCols - 1
                                Select Case r
                                    Case 0
                                        .Columns(c) = Proper(.WRDBDataSource.Items(c))
                                    Case 1
                                        .CCodes(c) = .WRDBDataSource.Items(c).ToUpper
                                    Case 2
                                        .Multipliers(c) = .WRDBDataSource.Items(c).ToUpper
                                End Select
                            Next c
                        Next r

                        'handle case where legacy import file has field not in support table
                        If dgvhDefaults IsNot Nothing Then
                            dgvhDefaults.SetCellFormatList(0, 1, ";" & WRDBImport.ValidValueList(clsWRDBImport.enumTables.tStationTable), .StationID)
                            dgvDefaults.Item(0, 1).Value = .StationID
                        End If

                    Case clsWRDBImport.enumFormat.HourDay

                        .WRDBDataSource.Rewind()

                        .NumCols = 32 '(time column plus 31 days)

                        'line 1
                        If Not .WRDBDataSource.Read Or .WRDBDataSource.NumItems < 2 Then Return False
                        .Description = .WRDBDataSource.Items(1)

                        'line 2
                        If Not .WRDBDataSource.Read Or .WRDBDataSource.NumItems < 7 Then Return False
                        .StationID = .WRDBDataSource.Items(0)
                        .DataMonth = Val(.WRDBDataSource.Items(1)) 'month
                        If .DataMonth = 0 Then .DataMonth = ListItem(.WRDBDataSource.Items(1), .MonthList)
                        .DataYear = Val(.WRDBDataSource.Items(2)) 'year
                        .DST = (Val(.WRDBDataSource.Items(3)) = 1)
                        .PCode = .WRDBDataSource.Items(4).ToUpper
                        .CCode = .WRDBDataSource.Items(5).ToUpper
                        .Multiplier = Val(.WRDBDataSource.Items(6))

                        'line 3
                        If Not .WRDBDataSource.Read Then Return False
                        .Columns(0) = "Time"
                        .CCodes(0) = ""
                        .Multipliers(0) = ""
                        .ConversionGroups(0) = "(None)"
                        .Filters(0) = ""
                        For c = 1 To .WRDBDataSource.NumItems - 1
                            .Columns(c) = "Day " & .WRDBDataSource.Items(c)
                            .CCodes(c) = ""
                            .Multipliers(c) = 1
                            .ConversionGroups(c) = "(None)"
                            .Filters(c) = ""
                        Next c

                        'handle case where legacy import file has field not in support table (add empty item so can deselect)
                        dgvhDefaults.SetCellFormatList(0, 1, ";" & WRDBImport.ValidValueList(clsWRDBImport.enumTables.tStationTable), .StationID)
                        dgvhDefaults.SetCellFormatList(0, 2, ";" & WRDBImport.ValidValueList(clsWRDBImport.enumTables.tPCodeTable), .PCode)
                        dgvhDefaults.SetCellFormatList(0, 3, ";" & WRDBImport.ValidValueList(clsWRDBImport.enumTables.tCCodeTable), .CCode)

                    Case clsWRDBImport.enumFormat.DateHour

                        .WRDBDataSource.Rewind()

                        'line 1
                        If Not .WRDBDataSource.Read Or .WRDBDataSource.NumItems < 2 Then Return False
                        .Description = .WRDBDataSource.Items(1)

                        'line 2
                        If Not .WRDBDataSource.Read Or .WRDBDataSource.NumItems < 5 Then Return False
                        .StationID = .WRDBDataSource.Items(0).ToUpper
                        .DST = (Val(.WRDBDataSource.Items(1)) = 1)
                        .PCode = UCase(.WRDBDataSource.Items(2)).ToUpper
                        .CCode = UCase(.WRDBDataSource.Items(3))
                        .Multiplier = Val(.WRDBDataSource.Items(4))

                        'line 3
                        If Not .WRDBDataSource.Read Then Return False
                        .NumCols = .WRDBDataSource.NumItems + 1
                        For c = 0 To .NumCols - 1
                            .Columns(c) = "Hour " & .WRDBDataSource.Items(c)
                            .CCodes(c) = ""
                            .Multipliers(c) = 1
                            .ConversionGroups(c) = "(None)"
                            .Filters(c) = ""
                        Next c

                        'handle case where legacy import file has field not in support table
                        dgvhDefaults.SetCellFormatList(0, 1, ";" & WRDBImport.ValidValueList(clsWRDBImport.enumTables.tStationTable), .StationID)
                        dgvhDefaults.SetCellFormatList(0, 2, ";" & WRDBImport.ValidValueList(clsWRDBImport.enumTables.tPCodeTable), .PCode)
                        dgvhDefaults.SetCellFormatList(0, 3, ";" & WRDBImport.ValidValueList(clsWRDBImport.enumTables.tCCodeTable), .CCode)

                    Case clsWRDBImport.enumFormat.DayMonth

                        .WRDBDataSource.Rewind()

                        'line 1
                        If Not .WRDBDataSource.Read Or .WRDBDataSource.NumItems < 2 Then Return False
                        .Description = .WRDBDataSource.Items(1)

                        'line 2
                        If Not .WRDBDataSource.Read Or .WRDBDataSource.NumItems < 6 Then Return False
                        .StationID = .WRDBDataSource.Items(0)

                        .DataTime = .WRDBDataSource.Items(1)
                        .DataYear = Val(.WRDBDataSource.Items(2))
                        .PCode = UCase(.WRDBDataSource.Items(3))
                        .CCode = UCase(.WRDBDataSource.Items(4))
                        .Multiplier = Val(.WRDBDataSource.Items(5))

                        'line 3
                        If Not .WRDBDataSource.Read Then Return False
                        .NumCols = .WRDBDataSource.NumItems
                        For c = 0 To .NumCols - 1
                            .Columns(c) = .WRDBDataSource.Items(c)
                            i = ListItem(.Columns(c), .MonthList)
                            If i = 0 Then i = Val(.Columns(c))
                            If i >= 1 And i <= 12 Then
                                .Columns(c) = Choose(i, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")
                                .CCodes(c) = ""
                                .Multipliers(c) = 1
                                .ConversionGroups(c) = "(None)"
                                .Filters(c) = ""
                            End If
                        Next c

                        'handle case where legacy import file has field not in support table
                        dgvhDefaults.SetCellFormatList(0, 1, ";" & WRDBImport.ValidValueList(clsWRDBImport.enumTables.tStationTable), .StationID)
                        dgvhDefaults.SetCellFormatList(0, 2, ";" & WRDBImport.ValidValueList(clsWRDBImport.enumTables.tPCodeTable), .PCode)
                        dgvhDefaults.SetCellFormatList(0, 3, ";" & WRDBImport.ValidValueList(clsWRDBImport.enumTables.tCCodeTable), .CCode)

                    Case clsWRDBImport.enumFormat.USGS

                        .Description = "Data downloaded by BASINS and imported from " & IO.Path.GetFileName(.ImportFilename)
                        sr = New IO.StreamReader(WRDBImport.ImportFilename)
                        Dim LastLine As String
                        Dim ReadingPCodes As Boolean = False
                        Do
                            LastLine = sr.ReadLine
                            If LastLine Is Nothing Then Exit Do
                            Dim item() As String = LastLine.Split(New Char() {" "}, StringSplitOptions.RemoveEmptyEntries)
                            If item.Length >= 3 AndAlso item(0) = "#" Then 'may be three item header in BASINS download
                                Select Case item(1)
                                    Case "station_nm"
                                        .StationName = ""
                                        For j As Integer = 2 To item.Length - 1
                                            .StationName &= item(j) & " "
                                        Next
                                        .StationName = Proper(.StationName.Trim)
                                        .StationType = "USGS FLOW"
                                    Case "huc_cd" : .HUC = item(2)
                                    Case "dec_lat_va" : .Latitude = item(2)
                                    Case "dec_long_va" : .Longitude = item(2)
                                    Case "drain_area_va" : .DrArea = item(2)
                                    Case "agency_cd" : .Agency = item(2)
                                End Select
                                If ReadingPCodes And item.Length >= 4 Then
                                    Dim Anal_Name As String = ""
                                    For j As Integer = 3 To item.Length - 1
                                        Anal_Name &= item(j) & " "
                                    Next
                                    If Not .PCodes.ContainsKey(item(1)) Then .PCodes.Add(item(1), Anal_Name)
                                End If
                            End If
                            If ReadingPCodes And LastLine.Trim = "#" Then ReadingPCodes = False 'have finished pcodes section
                            If LastLine.StartsWith("# The following parameters", StringComparison.OrdinalIgnoreCase) Then ReadingPCodes = True
                        Loop Until Not LastLine.StartsWith("#")
                        'next line is tab-delimited column headers
                        Dim col() As String = LastLine.Split(vbTab)
                        .NumCols = col.Length
                        If .NumCols = 1 Then Return False
                        For c = 0 To .NumCols - 1
                            Select Case col(c)
                                Case "site_no" : .Columns(c) = "Station_ID"
                                Case "agency_cd" : .Columns(c) = "Agency"
                                Case "measurement_dt", "datetime" : .Columns(c) = "Date_Time"
                                Case "sample_dt" : .Columns(c) = "Date"
                                Case "sample_tm" : .Columns(c) = "Time"
                                Case "date_time" : .Columns(c) = "Date_Time_Comb"
                                Case "parm_cd" : .Columns(c) = "PCode"
                                Case "remark_cd" : .Columns(c) = "RCode"
                                Case "result_va", "value" : .Columns(c) = "Result"
                                Case "discharge_1"
                                    .Columns(c) = "Result"
                                    'set global pcode for import; look at pcode list to guess the appropriate code
                                    'assume want to use STORET code first, but override with CRMP code if found
                                    .PCode = SelectedPCode
                                    'If ListItem("00061", .ValidFieldList(clsWRDBImport.enumTables.tPCodeTable)) <> 0 Then .PCode = "00061" 'instantaneous
                                    'If ListItem("FLOWCFS", .ValidFieldList(clsWRDBImport.enumTables.tPCodeTable)) <> 0 Then .PCode = "FLOWCFS" 'instantaneous
                                    If .PCode = "" And WRDBImport.SkipPreview Then 'must prompt user for valid pcode
                                        .PCode = InputBox("Please enter the PCode you wish to assign to the instantaneous discharge:", "Enter Missing PCode", "FLOWCFS")
                                        If .PCode = "" Then Return False
                                        SelectedPCode = .PCode
                                    End If
                                Case Else
                                    If col(c) Like "*_00060_00003" Then
                                        .Columns(c) = "Result"
                                        'set global pcode for import; look at pcode list to guess the appropriate code
                                        'assume want to use STORET code first, but override with CRMP code if found
                                        .PCode = SelectedPCode
                                        'If ListItem("00060", .ValidFieldList(clsWRDBImport.enumTables.tPCodeTable)) <> 0 Then .PCode = "00060" 'daily average
                                        'If ListItem("FLOWCFSDA", .ValidFieldList(clsWRDBImport.enumTables.tPCodeTable)) <> 0 Then .PCode = "FLOWCFSDA" 'daily average
                                        If .PCode = "" And WRDBImport.SkipPreview Then 'must prompt user for valid pcode
                                            .PCode = InputBox("Please enter the PCode you wish to assign to the instantaneous discharge:", "Enter Missing PCode", "FLOWCFSDA").ToUpper
                                            If .PCode = "" Then Return False
                                            SelectedPCode = .PCode
                                        End If
                                    Else
                                        .Columns(c) = "Ignore"
                                    End If
                            End Select
                            .CCodes(c) = ""
                            .Multipliers(c) = 1
                            .ConversionGroups(c) = "(None)"
                            .Filters(c) = ""
                        Next

                    Case Else

                        .Description = "Data Imported from " & IO.Path.GetFileName(.ImportFilename)
                        .StationID = ""
                        .StationGroup = ""
                        .NumCols = .WRDBDataSource.FieldNames.Count
                        .Increment = 1
                        .IncrementType = clsWRDBImport.enumIncrement.incrRow
                        .DST = False
                        .PCode = ""
                        .PCodeGroup = ""
                        .CCode = ""
                        .DataAgency = ""
                        .Multiplier = 1

                        For c = 0 To .NumCols - 1
                            If ItemIn(.WRDBDataSource.FieldNames(c).ToUpper, TreeList.ToUpper.Split(";")) Then
                                .Columns(c) = Proper((.WRDBDataSource.FieldNames(c)))
                            Else
                                .Columns(c) = "Ignore"
                            End If
                            .CCodes(c) = ""
                            .Multipliers(c) = 1
                            .ConversionGroups(c) = "(None)"
                            .Filters(c) = ""
                        Next c
                End Select

                If HeaderFile <> "" Then
                    .CCode = GetKey(IniFile, "General", "CCode")
                    .Description = GetKey(IniFile, "General", "Description")
                    .DST = GetKey(IniFile, "General", "DST", CStr(False))
                    .Increment = GetKey(IniFile, "General", "Increment", CStr(1))
                    .IncrementType = GetKey(IniFile, "General", "IncrementType", CStr(clsWRDBImport.enumIncrement.incrRow))
                    .Multiplier = GetKey(IniFile, "General", "Multiplier", 1)
                    .NumCols = GetKey(IniFile, "General", "NumCols", CStr(0))
                    .OtherDelimiter = GetKey(IniFile, "General", "OtherDelimiter", "|")
                    .PCode = GetKey(IniFile, "General", "PCode")
                    .PCodeGroup = GetKey(IniFile, "General", "PCodeGroup")
                    .StationID = GetKey(IniFile, "General", "StationID")
                    .StationGroup = GetKey(IniFile, "General", "StationGroup")
                    .DataMonth = GetKey(IniFile, "General", "Month", "0")
                    .DataDay = GetKey(IniFile, "General", "Day", "0")
                    .DataYear = GetKey(IniFile, "General", "Year", "0")
                    .DataTime = GetKey(IniFile, "General", "Time", "")
                    .DataAgency = GetKey(IniFile, "General", "Agency", "")
                    .PCodeGroup = GetKey(IniFile, "General", "PCodeGroup", "")
                    .StationGroup = GetKey(IniFile, "General", "StationGroup", "")
                    .ValidateSupport = GetKey(IniFile, "General", "ValidateSupport", CStr(True))
                    .RCodeConvGroup = GetKey(IniFile, "General", "ConvertRCodes", CStr(False))
                    .CultureName = GetKey(IniFile, "General", "CultureName", "(Current")
                    For i = 0 To .NumCols - 1
                        .CCodes(i) = GetKey(IniFile, "CCodes", CStr(i + 1))
                        .Columns(i) = GetKey(IniFile, "Columns", CStr(i + 1))
                        .Multipliers(i) = GetKey(IniFile, "Multipliers", CStr(i + 1), CStr(1))
                        .ConversionGroups(i) = GetKey(IniFile, "ConversionGroups", CStr(i + 1), "(None)")
                        .Filters(i) = GetKey(IniFile, "Filters", CStr(i + 1), "")
                    Next i
                    Dim sDelim As String = GetKey(IniFile, "General", "Delimiter", ",")
                    .Delimiters = sDelim.Replace("<TAB>", vbTab)
                End If

            End With

            Return True

        Catch ex As Exception
            ErrorMsg(, ex)
            Return False
        Finally
            If sr IsNot Nothing Then
                sr.Close()
                sr.Dispose()
                sr = Nothing
            End If
            Initializing = False
        End Try

    End Function

    Private Sub btnContinue_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles btnContinue.Click
        SaveHeader(AppDataPath & "\LastHeader.hdr")
        GetHeaderFromForm()
    End Sub

    Private Sub btnHelp_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnHelp.Click
        Dim DLLPath As String = GetSetting(RegApp, "Defaults", "DLL Path " & My.Application.Info.Version.ToString(2), "C:\Program Files\Water Resources Database " & My.Application.Info.Version.ToString(2))
        Help.ShowHelp(Me, DLLPath & "\WRDB.chm", HelpNavigator.TopicId, "1")
    End Sub

    Private Sub btnLoad_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles btnLoad.Click
        Dim i As Short

        With WRDBImport

            If .ImportFilename.EndsWith("]") Then
                HeaderFile = .ImportFilename & ".hdr"
            Else
                HeaderFile = IO.Path.ChangeExtension(.ImportFilename, "hdr")
            End If

            With New OpenFileDialog
                .Filter = "Header Files (*.hdr)|*.hdr"
                .InitialDirectory = GetSetting(RegApp, "Defaults", "HeaderDir", My.Computer.FileSystem.SpecialDirectories.MyDocuments & "\WRDB")
                .Title = "Open Header File"
                .DefaultExt = ".hdr"
                .AddExtension = True
                If My.Computer.FileSystem.FileExists(HeaderFile) Then .FileName = HeaderFile 'only set to default filename if already exists; otherwise would insist on storing HDR files with import files
                If .ShowDialog(Me) = DialogResult.Cancel Then .Dispose() : Exit Sub
                HeaderFile = .FileName
                SaveSetting(RegApp, "Defaults", "HeaderDir", IO.Path.GetDirectoryName(.FileName))
                .Dispose()
            End With
            ReadHeader()
            RefreshHeader()
            'following reqd in case header file had different number of columns than import file
            dgvHeader.ColumnCount = dgvData.ColumnCount
            .NumCols = dgvHeader.ColumnCount
        End With
    End Sub

    Private Sub btnLoadLast_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoadLast.Click
        HeaderFile = AppDataPath & "\LastHeader.hdr"
        If My.Computer.FileSystem.FileExists(HeaderFile) Then
            ReadHeader()
            RefreshHeader()
            'following reqd in case header file had different number of columns than import file
            dgvHeader.ColumnCount = dgvData.ColumnCount
            WRDBImport.NumCols = dgvHeader.ColumnCount
        End If
    End Sub

    Private Sub btnOptions_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles btnOptions.Click
        Try
            With New frmOptions(WRDBImport)
                If .ShowDialog(Me) = Windows.Forms.DialogResult.OK Then
                    WRDBImport.ValidateSupport = .chkValidate.Checked
                    WRDBImport.RCodeConvGroup = .cboRCodes.Text
                    '8/12/10: no longer used
                    'WRDBImport.BypassImport = .chkBypass.Checked
                    WRDBImport.BypassImport = False
                    WRDBImport.CultureName = .cboCulture.Text
                    SaveSetting(RegApp, "General", "ValidateSupport", WRDBImport.ValidateSupport)
                    SaveSetting(RegApp, "General", "RCodeConvGrp", WRDBImport.RCodeConvGroup)
                    SaveSetting(RegApp, "General", "CultureName", WRDBImport.CultureName)
                End If
            End With
        Catch ex As Exception
            ErrorMsg(, ex)
        End Try
    End Sub

    Private Sub btnSave_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles btnSave.Click
        Dim i As Short

        With WRDBImport

            If HeaderFile = "" Then 'let default name be same as database and table
                If .ImportFilename Like "*]" Then
                    HeaderFile = .ImportFilename & ".hdr"
                Else
                    i = InStrRev(.ImportFilename, ".")
                    HeaderFile = VB.Left(.ImportFilename, i) & "hdr"
                End If
            End If

            With New SaveFileDialog
                .Filter = "Header File (*.hdr)|*.hdr"
                .DefaultExt = ".hdr"
                .AddExtension = True
                .CheckPathExists = True
                .OverwritePrompt = True
                .SupportMultiDottedExtensions = False
                .InitialDirectory = GetSetting(RegApp, "Defaults", "HeaderDir", My.Computer.FileSystem.SpecialDirectories.MyDocuments & "\WRDB")
                .Title = "Save Header File"
                'no longer want to force header to be same as import filename
                '.FileName = HeaderFile
                If .ShowDialog(Me) = Windows.Forms.DialogResult.Cancel Then .Dispose() : Exit Sub
                HeaderFile = .FileName
                SaveSetting(RegApp, "Defaults", "HeaderDir", IO.Path.GetDirectoryName(.FileName))
                .Dispose()
            End With

            SaveHeader(HeaderFile)
        End With

    End Sub

    Private Sub cboImportIndex_SelectionChangeCommitted(ByVal sender As Object, ByVal e As System.EventArgs) Handles cboImportIndex.SelectionChangeCommitted
        WRDBImport.WRDBDataSource.ActiveTable = cboImportIndex.Text
        WRDBImport.NumCols = WRDBImport.WRDBDataSource.FieldNames.Count
        LoadForm()
    End Sub

    Private Sub chkDelimTab_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles chkDelimTab.CheckedChanged, chkDelimComma.CheckedChanged, chkDelimSpaces.CheckedChanged, chkDelimOther.CheckedChanged, txtDelimOther.TextChanged
        Application.DoEvents()
        LoadForm()
    End Sub

    'Private Sub btnView_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles btnView.Click

    '    With WRDBImport
    '        If UCase(.ImportFile) Like "*.MDB*" Or UCase(.ImportFile) Like "*.DB" Or UCase(.ImportFile) Like "*.DBF" Or UCase(.ImportFile) Like "*.XLS*" Then

    '            With New frmTableBrowser
    '                .SetTable(WRDBImport.ImportFile, chkUseHeadings.Checked)
    '                .ShowDialog()
    '            End With

    '        Else
    '            Shell("write """ & .ImportFile & """", AppWinStyle.NormalFocus)
    '        End If
    '    End With

    'End Sub

    Private Sub chkUseHeadings_CheckStateChanged(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles chkUseHeadings.CheckStateChanged
        If Initializing Then Exit Sub
        WRDBImport.UseHeadings = chkUseHeadings.Checked
        LoadForm()
    End Sub

    Private Sub dgvDefaults_DataError(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewDataErrorEventArgs) Handles dgvDefaults.DataError
        Static AlreadyShown As Boolean = False
        If Not AlreadyShown Then ErrorMsg(, e.Exception)
        AlreadyShown = True
    End Sub

    Private Sub dgvHeader_CellClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvHeader.CellClick
        If e.RowIndex = 0 And e.ColumnIndex >= 0 Then 'is link; show treeview
            If TreeviewForm Is Nothing Then TreeviewForm = New frmTreeView(TreeList)
            With dgvHeader
                Dim pt As Point = .GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, True).Location
                pt.Offset(0, .GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, True).Height)
                TreeviewForm.Location = .PointToScreen(pt)
                If TreeviewForm.ShowDialog(Me) = Windows.Forms.DialogResult.OK Then
                    dgvHeader.Item(e.ColumnIndex, e.RowIndex).Value = TreeviewForm.SelectedItem
                End If
            End With
        End If
    End Sub

    Private Sub EnableDelimiters(ByRef IsEnabled As Boolean)
        fraDelim.Enabled = IsEnabled
    End Sub

    Private Sub fraData_SizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles fraData.SizeChanged
        Const NumPadding = 10
        If WRDBImport Is Nothing Then Exit Sub
        Dim sCaption As String = "Data in Import File " & Proper(WRDBImport.ImportFilename)
        Dim g As Graphics = fraData.CreateGraphics
        Dim wid As Integer = g.MeasureString(sCaption & "".PadRight(NumPadding, "_"), fraData.Font, 9999).Width
        If wid > fraData.Width Then 'is too wide to display
            While sCaption.Length > 1
                sCaption = sCaption.Remove(sCaption.Length / 2, 1)
                wid = g.MeasureString(sCaption & "".PadRight(NumPadding, "_"), fraData.Font, 9999).Width
                If wid <= fraData.Width Then Exit While
            End While
            sCaption = sCaption.Insert(sCaption.Length / 2, "...")
        End If
        g.Dispose()
        fraData.Text = sCaption
    End Sub

    Private Sub frmPreviewData_FormClosed(ByVal eventSender As System.Object, ByVal eventArgs As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        If TreeviewForm IsNot Nothing Then TreeviewForm.Dispose()
        SaveWindowPos(RegApp, Me)
    End Sub

    Private Sub frmPreviewData_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Load
        GetWindowPos(RegApp, Me)
        ReplaceTooltipAndHelpText(Me, Nothing, HelpProvider1)
        With dgvHeader
            .RowCount = 5
            .ColumnHeadersVisible = False
            .ScrollBars = ScrollBars.Both
        End With
        Show()
        Initialize()
        Application.DoEvents()
        Me.BringToFront()
    End Sub

    Private Sub GetHeaderFromForm()
        Dim i As Short

        With WRDBImport
            .UseHeadings = chkUseHeadings.Checked
            .Increment = Val(txtRowIncr.Text)
            .IncrementType = cboIncrement.SelectedIndex
            .DST = chkDST.Checked
            .OtherDelimiter = txtDelimOther.Text
            .Delimiters = IIf(Me.chkDelimTab.Checked, vbTab, "") & IIf(Me.chkDelimComma.Checked, ",", "") & IIf(Me.chkDelimSpaces.Checked, " ", "") & IIf(Me.chkDelimOther.Checked, .OtherDelimiter, "")

            .Description = dgvDefaults.Item(0, 0).Value
            .StationID = dgvDefaults.Item(0, 1).Value
            .PCode = dgvDefaults.Item(0, 2).Value
            .CCode = dgvDefaults.Item(0, 3).Value
            .DataAgency = dgvDefaults.Item(0, 4).Value
            .DataMonth = Val(dgvDefaults.Item(0, 5).Value)
            .DataDay = Val(dgvDefaults.Item(0, 6).Value)
            .DataYear = Val(dgvDefaults.Item(0, 7).Value)
            .DataTime = dgvDefaults.Item(0, 8).Value
            .LEW_Pct = dgvDefaults.Item(0, 9).Value
            .Depth_M = dgvDefaults.Item(0, 10).Value
            .Multiplier = Val(dgvDefaults.Item(0, 11).Value)
            .StationGroup = dgvDefaults.Item(0, 12).Value
            .PCodeGroup = dgvDefaults.Item(0, 13).Value
            For i = 0 To dgvHeader.ColumnCount - 1
                .Columns(i) = dgvHeader.Item(i, 0).Value
                .CCodes(i) = IIf(dgvHeader.Item(i, 1).Value Is Nothing, "", dgvHeader.Item(i, 1).Value)
                .Multipliers(i) = IIf(dgvHeader.Item(i, 2).Value Is Nothing, "1", dgvHeader.Item(i, 2).Value)
                .ConversionGroups(i) = IIf(dgvHeader.Item(i, 3).Value Is Nothing, "(None)", dgvHeader.Item(i, 3).Value)
                .Filters(i) = IIf(dgvHeader.Item(i, 4).Value Is Nothing, "", dgvHeader.Item(i, 4).Value)
            Next i
        End With

    End Sub

    Public Sub Initialize()

        Dim ext As String

        With WRDBImport
            ext = IO.Path.GetExtension(.ImportFilename).ToUpper

            Initializing = True 'so changing state doesn't trigger reread

            'these table types will always have header (field names)
            If ItemIn(ext, ".MDB", ".DBF", ".BMD", ".WDM", ".DSS", ".OUT", ".AIR", ".DAT") Then
                chkUseHeadings.Checked = True
                chkUseHeadings.Enabled = False
                fraDelim.Enabled = False
            ElseIf ext = ".DB" Then
                chkUseHeadings.Checked = True
                chkUseHeadings.Enabled = False
                fraDelim.Enabled = False
                chkDelimTab.Checked = True
            ElseIf ext Like ".XLS*" Then 'XLS will usually have headers, but not always
                chkUseHeadings.Checked = True
                chkUseHeadings.Enabled = True
                fraDelim.Enabled = False
            ElseIf .DataFormat = clsWRDBImport.enumFormat.USGS Then
                chkUseHeadings.Checked = True
                chkUseHeadings.Enabled = False
                fraDelim.Enabled = False
                chkDelimTab.Checked = True
            ElseIf .DataFormat <> clsWRDBImport.enumFormat.DataTable Then
                chkUseHeadings.Checked = False
                chkUseHeadings.Enabled = False
                fraDelim.Enabled = True
            Else
                chkUseHeadings.Checked = .UseHeadings
                chkUseHeadings.Enabled = True
                fraDelim.Enabled = True
            End If

            .UseHeadings = chkUseHeadings.Checked

            If fraDelim.Enabled Then
                'read the first 1000 lines to check for import file keyword and delimiters
                Dim sr As New IO.StreamReader(WRDBImport.ImportFilename)
                Dim sb As New System.Text.StringBuilder
                Dim i As Integer = 0
                Do While Not sr.EndOfStream And i <= 1000
                    sb.Append(sr.ReadLine)
                    i += 1
                Loop
                sr.Close()
                sr.Dispose()
                sr = Nothing
                Dim s As String = sb.ToString

                If ext = ".TXT" Then
                    If s.Contains(vbTab) Then
                        chkDelimTab.Checked = True
                    ElseIf s.Contains(",") Then
                        chkDelimComma.Checked = True
                    ElseIf s.Contains(" ") Then
                        chkDelimSpaces.Checked = True
                    End If
                ElseIf ext = ".CSV" Then
                    chkDelimComma.Checked = True
                Else
                    If s.Contains(vbTab) Then chkDelimTab.Checked = True
                    If s.Contains(",") Then chkDelimComma.Checked = True
                    If s.Contains(" ") Then chkDelimSpaces.Checked = True
                End If
            End If

            With dgvDefaults
                .ColumnHeadersVisible = False
                .RowCount = 14
                .ColumnCount = 1
                .Columns(0).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
                .RowHeadersWidth = 100
                For c As Integer = 0 To .ColumnCount - 1
                    .Columns(c).SortMode = DataGridViewColumnSortMode.NotSortable
                Next
                .Rows(0).HeaderCell.Value = "Description" : .Item(0, 0).ValueType = GetType(String)
                .Rows(1).HeaderCell.Value = "Station ID" : .Item(0, 1).ValueType = GetType(String)
                .Rows(2).HeaderCell.Value = "PCode" : .Item(0, 2).ValueType = GetType(String)
                .Rows(3).HeaderCell.Value = "CCode" : .Item(0, 3).ValueType = GetType(String)
                .Rows(4).HeaderCell.Value = "Agency" : .Item(0, 4).ValueType = GetType(String)
                .Rows(5).HeaderCell.Value = "Month" : .Item(0, 4).ValueType = GetType(String)
                .Rows(6).HeaderCell.Value = "Day" : .Item(0, 5).ValueType = GetType(String)
                .Rows(7).HeaderCell.Value = "Year" : .Item(0, 6).ValueType = GetType(String)
                .Rows(8).HeaderCell.Value = "Time" : .Item(0, 7).ValueType = GetType(String)
                .Rows(9).HeaderCell.Value = "LEW_Pct" : .Item(0, 8).ValueType = GetType(String)
                .Rows(10).HeaderCell.Value = "Depth_M" : .Item(0, 9).ValueType = GetType(String)
                .Rows(11).HeaderCell.Value = "Multiplier" : .Item(0, 10).ValueType = GetType(String)
                .Rows(12).HeaderCell.Value = "Station Grp" : .Item(0, 11).ValueType = GetType(String)
                .Rows(13).HeaderCell.Value = "PCode Grp" : .Item(0, 12).ValueType = GetType(String)
                If WRDBImport.AssumeSupport Then
                    For i As Integer = 1 To .Rows.Count - 1
                        .Rows(i).Visible = False
                    Next
                End If
            End With

            'TreeList = String.Format("Ignore;Stations;>;{16};<;PCodes;>;{15};<;Data Fields;>;{0};<;Date & Time Fields;>;{1};<;Day of Month Fields;>;{2};<;Hour of Day Fields;>;{3};<;Month Fields;>;{4};<;Storet Fields;>;{5};<;Convert Fields;>;{6};<;Station Fields;>;{7};<;PCode Fields;>;{8};<;CCode Fields;>;{9};<;RCode Fields;>;{10};<;QCode Fields;>;{11};<;Station Group Fields;>;{12};<;PCode Group Fields;>;{13};<;Branch Fields;>;{14};<", .DataFieldList, .DateFieldList, .DayList, .HourList, .MonthList, .StoretFieldList, .ConvertFieldList, .StationFieldList, .PCodeFieldList, .CCodeFieldList, .RCodeFieldList, .QCodeFieldList, .StationGroupFieldList, .PCodeGroupFieldList, .BranchFieldList, .ValidFieldList(clsWRDBImport.enumTables.tPCodeTable), .ValidFieldList(clsWRDBImport.enumTables.tStationTable))

            .ValidateSupport = GetSetting(RegApp, "General", "ValidateSupport", True)
            .RCodeConvGroup = GetSetting(RegApp, "General", "RCodeConvGrp", "(None)")
            .CultureName = GetSetting(RegApp, "General", "CultureName", "(Current)")

        End With

        With dgvData
            .ColumnHeadersVisible = True
            .RowCount = 1001
            .ReadOnly = True
        End With

        dgvhDefaults = New WRDB.Controls.DGVEditor(dgvDefaults, WRDBImport.GridFont, WRDB.Controls.DGVEditor.enumReportScaling.ScaledFonts, WRDBImport.printDoc)
        With dgvhDefaults
            .SetCellFormatList(0, 1, ";" & WRDBImport.ValidValueList(clsWRDBImport.enumTables.tStationTable), , True) 'allow editable comboboxes so can enter code that doesn't already exist in support
            .SetCellFormatList(0, 2, ";" & WRDBImport.ValidValueList(clsWRDBImport.enumTables.tPCodeTable), , True)
            .SetCellFormatList(0, 3, ";" & WRDBImport.ValidValueList(clsWRDBImport.enumTables.tCCodeTable), , True)
            .SetCellFormatList(0, 4, ";" & WRDBImport.ValidValueList(clsWRDBImport.enumTables.tAgencyTable), , True)
        End With

        With cboImportIndex
            If ItemIn(ext, ".MDB", ".BMD", ".WDM", ".DSS", ".XLS", ".XLSX", ".XLSM") Then
                If WRDBImport.WRDBDataSource Is Nothing Then Close() : Exit Sub
                .Visible = True
                .Items.AddRange(WRDBImport.WRDBDataSource.TableNames.ToArray)
                .SelectedIndex = IIf(.Items.Count = 0, -1, 0)
                If Not String.IsNullOrEmpty(WRDBImport.WRDBDataSource.ActiveTable) Then .Text = WRDBImport.WRDBDataSource.ActiveTable.Replace("$", "").Replace("[", "").Replace("]", "")
                If .Text <> "" Then WRDBImport.WRDBDataSource.ActiveTable = .Text
                With lblImportIndex
                    If ItemIn(ext, ".MDB") Then
                        .Text = "Table:"
                    ElseIf ext = ".BMD" Then
                        .Text = "Segment:"
                    ElseIf ext = ".DSS" Then
                        .Text = "Data Path:"
                    ElseIf ext = ".WDM" Then
                        .Text = "Dataset:"
                    ElseIf ext Like ".XLS*" Then
                        .Text = "Sheet:"
                    End If
                End With
            Else
                .Visible = False
                lblImportIndex.Visible = False
            End If
        End With

        Text = "Preview Import Data"

        'see if header file with same name is available, if so, offer to load it
        'If WRDBImport.ImportFile.EndsWith("]") Then
        '    HeaderFile = WRDBImport.ImportFile & ".hdr"
        'Else
        '    HeaderFile = IO.Path.ChangeExtension(WRDBImport.ImportFile, ".hdr")
        'End If

        'If Dir(HeaderFile) = "" Then
        '    HeaderFile = ""
        'Else
        '    If MessageBox.Show("A header file named " & HeaderFile & " was found in the same directory as the import file. Do you want to load it?", "WRDB Import", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.No Then HeaderFile = ""
        'End If

        Initializing = False

        LoadForm()

    End Sub

    Private Sub LoadForm()
        If Initializing Then Exit Sub
        If Not ReadHeader() Then
            WarningMsg("The format that was detected for this file requires a specific arrangement of data, however the file header could not be properly interpreted; please check the file and compare with the requirements described in the help manual.")
            Exit Sub
        End If
        RefreshHeader()
        PreviewData()
    End Sub

    ''' <summary>
    ''' Read body of data file and place up to 50000 lines in preview grid assumed input file (or table) is already open and positioned to the record following the header for this type of import file.
    ''' </summary>
    ''' <remarks>Will close file/data reader when done</remarks>
    Private Sub PreviewData()
        Application.UseWaitCursor = True
        Application.DoEvents()

        With dgvData
            .RowCount = 1000
            .ColumnCount = dgvHeader.ColumnCount
            .ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
            .RowHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft
            .RowHeadersVisible = True
            .RowHeadersWidth = 100

            For c As Integer = 0 To .ColumnCount - 1 ' WRDBImport.WRDBDataSource.FieldNames.Count - 1
                If WRDBImport.UseHeadings Then
                    .Columns(c).HeaderText = Proper(WRDBImport.WRDBDataSource.FieldNames(c))
                Else
                    If c < 26 Then
                        .Columns(c).HeaderText = Chr(Asc("A") + c)
                    Else
                        .Columns(c).HeaderText = New String(Chr(Asc("A") + c - 26), 2)
                    End If
                End If
            Next c

            If WRDBImport.DataFormat = clsWRDBImport.enumFormat.USGS Then 'skip line after header line (contains field widths, etc.)
                WRDBImport.WRDBDataSource.Read()
            End If

            Dim r As Integer = 0
            Do While WRDBImport.WRDBDataSource.Read And r <= .RowCount - 1
                .Rows(r).HeaderCell.Value = CStr(r + 1)
                'For c As Integer = 0 To Min(.ColumnCount, WRDBImport.WRDBDataSource.FieldNames.Count) - 1
                For c As Integer = 0 To Min(.ColumnCount, WRDBImport.NumCols) - 1
                    .Item(c, r).Value = TestNull(WRDBImport.WRDBDataSource.Items(c), "")
                Next c
                r += 1
            Loop
            .RowCount = r

            dgvhData = New WRDB.Controls.DGVEditor(dgvData, WRDBImport.GridFont, WRDB.Controls.DGVEditor.enumReportScaling.ScaledFonts, WRDBImport.printDoc)

            'reset column widths
            With dgvHeader
                For c As Integer = 0 To .ColumnCount - 1
                    .Columns(c).AutoSizeMode = DataGridViewAutoSizeColumnMode.None
                    .AutoResizeColumn(c)
                Next c
            End With

            For c As Integer = 0 To .ColumnCount - 1
                .Columns(c).AutoSizeMode = DataGridViewAutoSizeColumnMode.None
                .AutoResizeColumn(c)
                Dim maxwidth As Integer = Max(.Columns(c).Width, dgvHeader.Columns(c).Width)
                .Columns(c).Width = maxwidth
                dgvHeader.Columns(c).Width = maxwidth
            Next c
        End With

        Application.UseWaitCursor = False
    End Sub

    Private Sub RefreshHeader()
        Dim r, c As Integer

        'place contents of header data structure on form; this data structure may have been filled
        'by contents of file or by loading a header file

        Initializing = True 'don't allow changes to form to call back here

        With WRDBImport

            'fill controls common to all formats (some may not be visible)

            cboIncrement.SelectedIndex = .IncrementType
            chkDST.Checked = .DST

            dgvDefaults.Item(0, 0).Value = .Description
            'note: need to test for existence of items in valid list or datagridview will return error
            dgvDefaults.Item(0, 1).Value = IIf(CType(dgvDefaults.Item(0, 1), DataGridViewComboBoxCell).Items.Contains(TestNull(.StationID, "")), .StationID, "")
            dgvDefaults.Item(0, 2).Value = IIf(CType(dgvDefaults.Item(0, 2), DataGridViewComboBoxCell).Items.Contains(TestNull(.PCode, "")), .PCode, "")
            dgvDefaults.Item(0, 3).Value = IIf(CType(dgvDefaults.Item(0, 3), DataGridViewComboBoxCell).Items.Contains(TestNull(.CCode, "")), .CCode, "")
            dgvDefaults.Item(0, 4).Value = IIf(CType(dgvDefaults.Item(0, 4), DataGridViewComboBoxCell).Items.Contains(TestNull(.DataAgency, "")), .DataAgency, "")
            dgvDefaults.Item(0, 5).Value = IIf(.DataMonth = 0, "", .DataMonth)
            dgvDefaults.Item(0, 6).Value = IIf(.DataDay = 0, "", .DataDay)
            dgvDefaults.Item(0, 7).Value = IIf(.DataYear = 0, "", .DataYear)
            dgvDefaults.Item(0, 8).Value = .DataTime
            dgvDefaults.Item(0, 9).Value = .LEW_Pct
            dgvDefaults.Item(0, 10).Value = .Depth_M
            dgvDefaults.Item(0, 11).Value = IIf(.Multiplier = 0, "", .Multiplier)
            dgvDefaults.Item(0, 12).Value = .StationGroup
            dgvDefaults.Item(0, 13).Value = .PCodeGroup

            'format for header
            With dgvHeader
                .ColumnCount = WRDBImport.NumCols
                .RowCount = 5
                .RowHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft
                .ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
                .RowHeadersWidth = 100
                .CurrentCell = .Item(0, 0)
                .ScrollBars = ScrollBars.Both
            End With
            dgvhHeader = New WRDB.Controls.DGVEditor(dgvHeader, WRDBImport.GridFont, WRDB.Controls.DGVEditor.enumReportScaling.ScaledFonts, WRDBImport.printDoc)
            txtRowIncr.Text = .Increment
            dgvHeader.RowHeadersVisible = True

            For r = 0 To 4
                dgvHeader.Rows(r).HeaderCell.Value = Choose(r + 1, "PCode/Field", "CCode", "Multiplier", "Conv Group", "Filter")
                For c = 0 To .NumCols - 1
                    If r = 0 Then
                        dgvhHeader.SetCellFormatLink(c, r)
                    ElseIf r = 1 Then
                        dgvhHeader.SetCellFormatList(c, r, ";" & WRDBImport.ValidValueList(clsWRDBImport.enumTables.tCCodeTable), .CCode)
                    ElseIf r = 3 Then
                        dgvhHeader.SetCellFormatList(c, r, WRDBImport.ValidValueList(clsWRDBImport.enumTables.tConvGroupTable), "(None)")
                    End If
                    dgvHeader.Item(c, r).Value = Choose(r + 1, .Columns(c), IIf(.FieldListContains(clsWRDBImport.enumTables.tCCodeTable, .CCodes(c)), .CCodes(c), ""), .Multipliers(c), .ConversionGroups(c), .Filters(c))
                    dgvHeader.Columns(c).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
                Next c
            Next r
            If WRDBImport.AssumeSupport Then
                For i As Integer = 1 To 2
                    dgvHeader.Rows(i).Visible = False
                Next
            End If
        End With

        Initializing = False

    End Sub

    Private Sub SaveHeader(ByVal HeaderFile As String)
        GetHeaderFromForm()

        If My.Computer.FileSystem.FileExists(HeaderFile) Then My.Computer.FileSystem.DeleteFile(HeaderFile)

        Dim IniFile As New WRDB.IniFile.clsIniFile(HeaderFile, True)

        With WRDBImport
            IniFile.SetKeyText("General", "UseHeadings", .UseHeadings)
            IniFile.SetKeyText("General", "CCode", .CCode)
            IniFile.SetKeyText("General", "Description", .Description)
            IniFile.SetKeyText("General", "DST", .DST)
            IniFile.SetKeyText("General", "Format", .DataFormat)
            IniFile.SetKeyText("General", "Increment", .Increment)
            IniFile.SetKeyText("General", "IncrementType", .IncrementType)
            IniFile.SetKeyText("General", "Month", .DataMonth)
            IniFile.SetKeyText("General", "Multiplier", .Multiplier)
            IniFile.SetKeyText("General", "NumCols", .NumCols)
            IniFile.SetKeyText("General", "OtherDelimiter", .OtherDelimiter)
            IniFile.SetKeyText("General", "PCode", .PCode)
            IniFile.SetKeyText("General", "StationID", .StationID)
            IniFile.SetKeyText("General", "Time", .DataTime)
            IniFile.SetKeyText("General", "Day", .DataDay)
            IniFile.SetKeyText("General", "Year", .DataYear)
            IniFile.SetKeyText("General", "ValidateSupport", .ValidateSupport)
            IniFile.SetKeyText("General", "ConvertRCodes", .RCodeConvGroup)
            IniFile.SetKeyText("General", "CultureName", .CultureName)
            IniFile.SetKeyText("General", "Agency", .DataAgency)
            IniFile.SetKeyText("General", "PCodeGroup", .PCodeGroup)
            IniFile.SetKeyText("General", "StationGroup", .StationGroup)
            For i As Integer = 0 To .NumCols - 1
                IniFile.SetKeyText("CCodes", CStr(i + 1), .CCodes(i))
                IniFile.SetKeyText("Columns", CStr(i + 1), .Columns(i))
                IniFile.SetKeyText("Multipliers", CStr(i + 1), .Multipliers(i))
                IniFile.SetKeyText("ConversionGroups", CStr(i + 1), .ConversionGroups(i))
                IniFile.SetKeyText("Filters", CStr(i + 1), .Filters(i))
            Next i
            IniFile.SetKeyText("General", "Delimiter", .Delimiters.Replace(vbTab, "<TAB>"))

            IniFile.Save()
        End With
    End Sub

    Private Sub ssData_Scroll1(ByVal sender As Object, ByVal e As System.Windows.Forms.ScrollEventArgs) Handles dgvData.Scroll
        dgvHeader.HorizontalScrollingOffset = dgvData.HorizontalScrollingOffset
    End Sub

    Private Sub ssHeader_Scroll1(ByVal sender As Object, ByVal e As System.Windows.Forms.ScrollEventArgs) Handles dgvHeader.Scroll
        dgvData.HorizontalScrollingOffset = dgvHeader.HorizontalScrollingOffset
    End Sub

    Private Sub btnView_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnView.Click
        Try
            With WRDBImport
                Dim ext As String = IO.Path.GetExtension(.ImportFilename).ToLower
                Select Case ext
                    Case ".txt", ".csv", ".rdb", ".out", ".air"
                        Shell(String.Format("write ""{0}""", .ImportFilename), AppWinStyle.NormalFocus)
                    Case ".dat"
                        Throw New IO.IOException("Unable to preview YSI data files.")
                    Case Else
                        Process.Start(.ImportFilename)
                End Select
            End With
        Catch ex As Exception
            ErrorMsg("Unable to view import file: " & WRDBImport.ImportFilename & "; the required application may not be installed on your system. For example, if the import file is a Paradox .db file, you need to have the Paradox application installed to view it.", ex)
        End Try
    End Sub
End Class